feat(cli): add rig config get|set <dot.path> — read/edit one key, then reconcile#20
Conversation
40ae438 to
3b29727
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 40ae438205
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3b29727 to
62831b9
Compare
…hen reconcile The recommended way to change a single setting without hand-editing YAML. get <dot.path> [--global] [--json] Reads one nested key from the single target file (./rig.yaml, or ~/.config/rig/config.yaml with --global) — NOT the cascade. A missing file or absent path exits non-zero; a mapping/list subtree prints as YAML; --json emits the JSON value (default=str, fail-soft). Diagnostics go to stderr so `get --json | jq` keeps a clean stdout. `--global` get works outside a git repo. set <dot.path> <value> [--global] [--no-apply] Coerces the value conservatively (true/false/int/float/null; leading-zero, nan/inf/1e3/underscore, and Unicode digits stay strings; quote-wrap forces a literal string), creates intermediate mappings, then guards the write with two pre-apply gates: schema validation, then a catalog-backed plan build over the full cascade (the same engine `rig apply` runs). On either failure — or a write IO error — the file is rolled back to its prior contents (a freshly-created file, and the immediate dir set created for it, are removed; a failed restore warns honestly). On success it reconciles immediately; --no-apply writes + prints the plan only. A repo-local set refuses when ./rig.yaml is absent (run `rig init` first) so built-in defaults never reconcile onto disk with no committed source. Setting the removed `scope` key is refused. Dot-path engine (split_path/get_path/set_path/coerce_scalar) and a public read_yaml_file live in riglib.config next to the loader/validator; version validation now rejects a bool (True == 1). install-skill's SKILL.md, install.sh, the dispatch SVG, README, and docs/config-schema.md document the command. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…olation The `rig config set … --global` second gate built the plan over the merged cascade (`_load_plan`), so a repo `rig.yaml` overriding the just-edited global key (e.g. a bad `agent_tools_source`, or a global catalog item ref) masked the breakage — the write persisted a global config that fails in every OTHER repo. Now, when the global file pins its OWN `agent_tools_source`, also build a plan over the global layer alone (`include_global=False`, no repo overlay) so its catalog-backed errors surface against the file itself and the write rolls back. A global file that legitimately defers the checkout to per-repo/env is untouched (no own coordinate to mask). Docs updated; regression test `test_cli_set_global_bad_value_not_masked_by_repo_override` (codex P2). Review note: the multi-model `review` binary is non-functional in this environment (reviewlib import fails on the system py3.14; the uv-bound cross-repo run exits without findings). Verified instead by TDD (red without the fix, green with it) + full suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62831b9 to
7c42864
Compare
|
Fixed in 9e76498 (rebased onto current main as 7c42864). The Regression test: |
…lidation (#36) Follow-up to the `rig config set --global` isolation gate (#20). Multi-model review flagged that the `agent_tools_source is None` early return — the branch that lets a global config legitimately defer its checkout to per-repo/env without a spurious catalog scan — had no test. Add one: a `--global` set of a non-catalog key, with a global file that pins no own `agent_tools_source`, must succeed and skip the isolated catalog scan (TDD-verified: drop the guard and the deferring config is wrongly rejected). Also fold in the review's small cleanups: trim the duplicated call-site comment (the why lives in the helper docstring) and drop a stray `(codex P2)` triage tag from a test comment. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ed by #34's wizard rebase) (#40) PR #34 (the `rig setup` wizard, merged as f054910) rebased over main's PR #20 (`rig config get|set`, 635eaf5) and kept the wizard's schema-key config CLI while deleting #20's dot-path CLI (cmd_config + helpers + parser + tests/test_config_getset.py). Only one `config` command can register, so the user-facing single-key editor regressed from the dot-path design to a schema-key one. This restores #20's dot-path CLI as the user-facing command, coexisting with the wizard. `rig config get|set` (restored, #20's design): - get <dot.path> [--global] [--json]: reads ONE nested key from the single target file (./rig.yaml, or ~/.config/rig/config.yaml with --global) — NOT the cascade. Missing file / absent path exits non-zero; a mapping/list subtree prints as YAML; --json emits the JSON value; diagnostics go to stderr. - set <dot.path> <value> [--global] [--no-apply]: conservative coercion (true/false/int/float/null; leading-zero, 1e3, nan/inf, underscored, Unicode digits stay strings), creates intermediate mappings, two pre-apply gates (schema.validate, then a catalog-backed plan build), rolls the file back on any failure, reconciles via the same engine as `rig apply`; --no-apply writes + prints the plan only. A repo-local set refuses when ./rig.yaml is absent. Setting the removed `scope` key is refused. The dot-path engine (split_path/get_path/set_path/coerce_scalar/read_yaml_file) was never deleted — #34 left it in riglib/config.py — so this restores only the CLI front-end (cmd_config + _cmd_config_get/_cmd_config_set + _config_target/ _read_target_yaml + the argparse wiring) plus tests/test_config_getset.py. The shared helpers (_load_plan/_print_plan/_print_results/_validate_layer_in_isolation/ _fmt_scalar) already existed identically in main. The wizard stays as `rig setup`. Its schema-key engine (owning-layer routing, effective_value, coerce, version-seeding) is internal to the wizard (setup_wizard.py/schema.py) and is not the `config get|set` command. The wizard reads/writes config via its own helpers, so dropping main's schema-based cmd_config breaks nothing in it. Removed the now-orphaned _fmt_config_value (its sole caller was the replaced cmd_config; #20 uses the identical _fmt_scalar). schema.option_for_key is now unreferenced in production but kept (public registry API, still tested, orphaned-by-this-replacement; dead-code rule: investigate, don't delete). Tests: restored tests/test_config_getset.py (59 tests). Removed the schema-key `config get|set` CLI tests from tests/test_setup_wizard.py (their CLI surface is replaced; the schema engine they exercised stays covered by the surviving test_coerce_*/test_effective_value_*/test_writable_layer_* and the wizard- interactive tests). Docs reconciled (README, AGENTS.md, docs/config-schema.md); the wizard's NON_INTERACTIVE_USAGE updated to the dot-path + reconcile framing. Full suite 800 passed / 8 skipped; smoke OK; gitleaks clean. Live-verified: get/--json/subtree/--global/--no-apply, coercion edge cases, no-file + scope guards. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The recommended way to change a single setting without hand-editing YAML.
get <dot.path> [--global] [--json]
Reads one nested key from the single target file (./rig.yaml, or
~/.config/rig/config.yaml with --global) — NOT the cascade. A missing file or
absent path exits non-zero; a mapping/list subtree prints as YAML; --json emits
the JSON value (default=str, fail-soft). Diagnostics go to stderr so
get --json | jqkeeps a clean stdout.--globalget works outside a git repo.set <dot.path> [--global] [--no-apply]
Coerces the value conservatively (true/false/int/float/null; leading-zero,
nan/inf/1e3/underscore, and Unicode digits stay strings; quote-wrap forces a
literal string), creates intermediate mappings, then guards the write with two
pre-apply gates: schema validation, then a catalog-backed plan build over the
full cascade (the same engine
rig applyruns). On either failure — or a writeIO error — the file is rolled back to its prior contents (a freshly-created file,
and the immediate dir set created for it, are removed; a failed restore warns
honestly). On success it reconciles immediately; --no-apply writes + prints the
plan only. A repo-local set refuses when ./rig.yaml is absent (run
rig initfirst) so built-in defaults never reconcile onto disk with no committed source.
Setting the removed
scopekey is refused.Dot-path engine (split_path/get_path/set_path/coerce_scalar) and a public
read_yaml_file live in riglib.config next to the loader/validator; version
validation now rejects a bool (True == 1). install-skill's SKILL.md, install.sh,
the dispatch SVG, README, and docs/config-schema.md document the command.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com